package com.study.component;

import org.redisson.api.*;
import org.redisson.config.Config;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @author zhuzi
 * 2024/3/25 11:07
 *
 * <a href="https://www.jianshu.com/p/43b816def80a">redissop </a>
 * RedisClientConfig 已经自动配置 RedissonClient
 * RedisClientConfig 读取得配置来源于redis 无需配置
 */

@Component
public class RedissonUtils {

    private static final String PREFIX = "REDISSON_LOCK:";
    @Resource
    private RedissonClient redissonClient;

    public void getRedissonClient() throws IOException {
        Config config = redissonClient.getConfig();
        System.out.println(config.toJSON().toString());
    }

    /**
     * 获取字符串对象
     *
     * @param objectName
     * @return
     */
    public <T> RBucket<T> getRBucket(String objectName) {
        RBucket<T> bucket = redissonClient.getBucket(PREFIX + objectName);
        return bucket;
    }

    /**
     * 获取Map对象
     *
     * @param objectName
     * @return
     */
    public <K, V> RMap<K, V> getRMap(String objectName) {
        RMap<K, V> map = redissonClient.getMap(PREFIX + objectName);
        return map;
    }

    /**
     * 获取有序集合
     *
     * @param objectName
     * @return
     */
    public <V> RSortedSet<V> getRSortedSet(String objectName) {
        RSortedSet<V> sortedSet = redissonClient.getSortedSet(PREFIX + objectName);
        return sortedSet;
    }

    /**
     * 获取集合
     *
     * @param objectName
     * @return
     */
    public <V> RSet<V> getRSet(String objectName) {
        RSet<V> rSet = redissonClient.getSet(PREFIX + objectName);
        return rSet;
    }

    /**
     * 获取列表
     *
     * @param objectName
     * @return
     */
    public <V> RList<V> getRList(String objectName) {
        RList<V> rList = redissonClient.getList(PREFIX + objectName);
        return rList;
    }

    /**
     * 获取队列
     *
     * @param objectName
     * @return
     */
    public <V> RQueue<V> getRQueue(String objectName) {
        RQueue<V> rQueue = redissonClient.getQueue(PREFIX + objectName);
        return rQueue;
    }

    /**
     * 获取双端队列
     *
     * @param objectName
     * @return
     */
    public <V> RDeque<V> getRDeque(String objectName) {
        RDeque<V> rDeque = redissonClient.getDeque(PREFIX + objectName);
        return rDeque;
    }


    /**
     * 获取锁
     *
     * @param objectName
     * @return
     */
    public RLock getRLock(String objectName) {
        RLock rLock = redissonClient.getLock(PREFIX + objectName);
        return rLock;
    }

    public Boolean tryLock(String key, long leaseTime, TimeUnit unit) {
        RLock rLock = redissonClient.getLock(PREFIX + key);

        boolean tryLock = false;
        try {
            tryLock = rLock.tryLock(0, leaseTime, unit);
        } catch (InterruptedException e) {
            return false;
        }
        return tryLock;
    }

    /**
     * 不配置超时时间 自动续期 默认 30秒
     *
     * @param key
     * @return
     */
    public Boolean tryLock(String key) {
        RLock rLock = redissonClient.getLock(PREFIX + key);
        boolean tryLock = false;
        try {
            tryLock = rLock.tryLock(0, -1L, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            return false;
        }
        return tryLock;
    }

    public Boolean verifyTryLock(RLock rLock, long leaseTime, TimeUnit unit) {
        boolean tryLock = false;
        try {
            tryLock = rLock.tryLock(0, leaseTime, unit);
        } catch (InterruptedException e) {
            return false;
        }
        return tryLock;
    }

    /**
     * 获取读取锁
     *
     * @param objectName
     * @return
     */
    public RReadWriteLock getRWLock(String objectName) {
        RReadWriteLock rwlock = redissonClient.getReadWriteLock(PREFIX + objectName);
        return rwlock;
    }

    /**
     * 获取原子锁
     *
     * @param objectName
     * @return
     */
    public RAtomicLong getRAtomicLong(String objectName) {
        RAtomicLong rAtomicLong = redissonClient.getAtomicLong(PREFIX + objectName);
        return rAtomicLong;
    }

    /**
     * 获取记数锁
     *
     * @param objectName
     * @return
     */
    public RCountDownLatch getRCountDownLatch(String objectName) {
        RCountDownLatch rCountDownLatch = redissonClient.getCountDownLatch(PREFIX + objectName);
        return rCountDownLatch;
    }
}
